大家好!今天的目標是實現一個基本但非常重要的功能,新增一個表單來加入新的待辦事項。
一個表單最基本的會有一個輸入框還有一個按鈕,我們將會示範如何使用 React Native 中的表單元件,例如 TextInput
,會用來收集使用者輸入的資料,並把它們保存到我們的待辦事項列表中。
在我們開始之前,讓我們先瞭解一下今天的程式碼。這是一個基本的待辦事項應用程式,我們有一個 inputText 的狀態來保存用戶輸入的文字,和一個 todos 的狀態來保存待辦事項的列表。每當用戶輸入一個新的待辦事項,我們會把它新增到 todos 的列表中。
TextInput
是 React Native 提供的一個基本元件,讓我們能夠讓使用者輸入一些文字。它相當於網頁開發中的 <input type="text">
元素。
讓我們把 TextInput
加進程式碼中:
export default function App() {
return (
<View style={styles.container}>
<TextInput
value={}
placeholder='請輸入事項'
onChangeText={}
/>
<StatusBar style='auto' />
</View>
)
}
接下來一一介紹這個元件所需要的一些 props 是什麼。
value
是這個 TextInput
當前輸入的值,等一下會使用 usestate
綁定到我們的狀態。placeholder
則是當這個輸入框是空的時候會顯示的提示文字。onChangeText
是當這個輸入框的值變化時會被調用的函數。
當使用者在 TextInput
裡面打字的時候,我們想要把他們輸入的文字收集起來,並保存到我們的狀態中。這時候就要通過建立一個函式和 useState
這個 Hook 來實現。
import { useState } from 'react'
export default function App() {
const [inputText, setInputText] = useState('')
const handleInputText = (text) => {
setInputText(text)
}
return (
<View style={styles.container}>
<TextInput
value={inputText}
placeholder='請輸入事項'
onChangeText={handleInputText}
/>
<StatusBar style='auto' />
</View>
)
}
在上面的程式碼中,handleInputText
這個函數,它會被當 TextInput
的值改變的時候調用,並且它會接收到一個參數,就是 TextInput
的當前值。
輸入完文字後,由於在手機 App 上並沒有像網頁那樣可以透過按下 Enter 鍵來做一個新增的動作,所以我們要建立一個按鈕來做這件事。
我們可以用 TouchableOpacity
來製作按鈕,並且使用 useState
來新增一個列表的狀態。
const [todos, setTodos] = useState([])
const handleAddItem = () => {
setTodos([
...todos,
{
id: todos.length,
text: inputText,
checked: false
}
])
}
return (
<View style={styles.container}>
<TextInput
value={inputText}
placeholder='請輸入事項'
onChangeText={handleInputText}
/>
<TouchableOpacity onPress={handleAddItem}>
<Text>新增</Text>
</TouchableOpacity>
<StatusBar style='auto' />
</View>
)
當使用者輸入了一個新的待辦事項,並點擊了新增按鈕之後,我們想要把這個新的待辦事項加入到我們的 todos
列表中。
這是通過 handleAddItem
實現的。這個函式會建立一個新的待辦事項的物件,然後用 setTodos
把這個新的待辦事項加入到 todos
列表中。
這邊說明一下建立的物件,裡面的 key 分別有 id、text 和 checked。id 是為了之後可以方便去比對做刪除與編輯,而 text 就是我們輸入並且會顯示在畫面上的文字,最後 checked 則是可以做一個表示完成與否的一個狀態。
最後我們要來美化一下今天做的表單,由於樣式設計不會是我們這個系列的重點,所以大家可以自己發揮,或者可以參考我的樣式,以下是今天完整的程式碼:
import { useState } from 'react'
import { StatusBar } from 'expo-status-bar'
import {
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
SafeAreaView
} from 'react-native'
export default function App() {
const [inputText, setInputText] = useState('')
const [todos, setTodos] = useState([])
const handleInputText = (text) => {
setInputText(text)
}
const handleAddItem = () => {
setTodos([
...todos,
{
id: todos.length,
text: inputText,
checked: false
}
])
}
return (
<SafeAreaView style={styles.container}>
<Text style={styles.title}>Todos</Text>
<View style={styles.inputArea}>
<TextInput
value={inputText}
placeholder='請輸入事項'
onChangeText={handleInputText}
style={styles.input}
/>
<TouchableOpacity onPress={handleAddItem} style={styles.button}>
<Text>新增</Text>
</TouchableOpacity>
</View>
<StatusBar style='auto' />
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
alignItems: 'center'
},
title: {
fontSize: 30,
fontWeight: 500,
alignSelf: 'flex-start',
marginBottom: 10,
color: '#eae6e6'
},
inputArea: {
flexDirection: 'row',
alignItems: 'center',
gap: 10
},
input: {
borderColor: '#bcb9b9',
borderWidth: 1,
borderRadius: 5,
height: '100%',
width: '80%',
paddingHorizontal: 15,
fontSize: 20,
backgroundColor: '#fff'
},
button: {
backgroundColor: '#fff',
padding: 10,
borderRadius: 5
}
})
今天展示了如何在 React Native 中建立一個簡單的表單來收集用戶的輸入,並把它加入到一個待辦事項的列表狀態中。
由於現在寫在 App.js
的程式碼有點多,所以明天會做好元件模組化,讓之後的開發更順暢。
明天見!